package com.maiji.cloud.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Lists;
import com.maiji.cloud.entities.login.*;
import com.maiji.cloud.request.BaseDataReqDto;
import com.maiji.cloud.request.BaseInputDto;
import com.maiji.cloud.request.ReqMetaData;
import com.maiji.cloud.request.SaveURBelongIdReqDto;
import com.maiji.cloud.request.login.AppVersionInfoReqData;
import com.maiji.cloud.request.login.CheckCodeReqData;
import com.maiji.cloud.request.login.MaijiArticleReqData;
import com.maiji.cloud.request.login.SendCodeReqDto;
import com.maiji.cloud.response.BaseDataResDto;
import com.maiji.cloud.response.BaseMetaResDto;
import com.maiji.cloud.response.BaseResDto;
import com.maiji.cloud.response.Status;
import com.maiji.cloud.response.login.*;
import com.maiji.cloud.response.shopingmall.BannerImgsResData;
import com.maiji.cloud.response.shopingmall.GetShoppingBannerImgsResDto;
import com.maiji.cloud.service.*;
import com.maiji.cloud.utils.CommonStringValueEnum;
import com.maiji.cloud.utils.MaijiOSS;
import com.maiji.cloud.utils.RedisUtil;
import com.maiji.cloud.utils.SMS;
import com.maiji.cloud.utils.UUID_MD5;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/common/")
public class CommonController {

    @Autowired
    private AppUserService appUserService;
    @Autowired
    private UploadRecordService uploadRecordService;
    @Autowired
	private MenuService menuService;
    @Autowired
    private RedisTemplate<String, Object> maiji1RedisTemplate;
    @Autowired
    private LabelService labelService;
    @Autowired
    private AppCarouselService appCarouselService;
    @Autowired
    private AppVersionInfoService appVersionInfoService;
    
    
    /**
     *  上传视频（批量）
     * @param uploadFiles
     * @param token
     * @return
     */
    @PostMapping("uploadVideos")
    public BaseDataResDto<List<UploadImageResData>> uploadVideos (@RequestBody MultipartFile[] uploadFiles,
                    @RequestHeader("maijiToken") String token, @RequestHeader("bucketName") String bucketName) {
        try {
            AppUser appUser = appUserService.checkToken(token);
            List<UploadRecord> uploadRecords = Lists.newArrayList();
            for (MultipartFile uploadFile: uploadFiles) {
                String fileName = uploadFile.getOriginalFilename();
                String fileExtName = fileName.substring(fileName.indexOf(".")+1);
                String objName = UUID_MD5.getUUID() + "." + fileExtName;
                if (! MaijiOSS.aliyunOSSUpload2(bucketName, objName, uploadFile.getInputStream()))
                    return new BaseDataResDto(Status.ERROR.setMessage("保存上传视频至阿里云OSS失败"));
                String url = "https://" + bucketName + ".oss-cn-beijing.aliyuncs.com/" + objName;
                URLConnection connection = new URL(url + "?x-oss-process=video/snapshot,t_1000,f_jpg,ar_auto").openConnection();
                BufferedImage bufferedImage = ImageIO.read(connection.getInputStream());
                String imgUrl = url + "?x-oss-process=video/snapshot,t_1000,f_jpg,w_500,ar_auto";
                uploadRecords.add(new UploadRecord()
                        .setUuId(UUID_MD5.getUUID())
                        .setUploadUserId(appUser.getUuId())
                        .setBucketName(bucketName)
                        .setFileName(objName)
                        .setHeight(bufferedImage.getHeight())
                        .setWidth(bufferedImage.getWidth())
                        .setUrl(url)
                        .setVideoCover(imgUrl)
                        .setUploadTime(new Date()));
            }
            if (! uploadRecordService.insertBatch(uploadRecords)) return new BaseDataResDto(Status.ERROR.setMessage("保存上传视频记录失败"));
            List<UploadImageResData> uploadImageResDataList = uploadRecords.stream().map(uploadRecord -> {
                UploadImageResData uploadImageResData = new UploadImageResData();
                BeanUtils.copyProperties(uploadRecord, uploadImageResData);
                return uploadImageResData;
            }).collect(Collectors.toList());
            return new BaseDataResDto(Status.SUCCESS).setData(uploadImageResDataList);
        } catch (Exception e) {
            e.printStackTrace();
            return new BaseDataResDto(Status.ERROR);
        }
    }

    /**
     *  上传图片（批量）
     * @param reqMap
     * @param token
     * @return
     */
    @PostMapping("uploadImage")
    public BaseDataResDto<List<UploadImageResData>> uploadImage (@RequestBody Map<String, Map<String, Object>> reqMap,
                                                                 @RequestHeader(name = "maijiToken", required = false) String token) {
        try {
            AppUser appUser = null;
            if (StringUtil.isNotBlank(token)) appUser = appUserService.checkToken(token);
            String userId = appUser != null ? appUser.getUuId() : "ManagerUser";
            List<UploadRecord> uploadRecords = reqMap.keySet().stream().map(key -> new UploadRecord()
                        .setUuId(UUID_MD5.getUUID())
                        .setUploadUserId(userId)
                        .setBucketName((String) reqMap.get(key).get("bucketName"))
                        .setFileName(key)
                        .setWidth((Integer) reqMap.get(key).get("width"))
                        .setHeight((Integer) reqMap.get(key).get("height"))
                        .setUrl((String) reqMap.get(key).get("url"))
                        .setUploadTime(new Date())
            ).collect(Collectors.toList());
            if (! uploadRecordService.insertBatch(uploadRecords))
                return new BaseDataResDto(Status.ERROR.setMessage("保存上传图片记录失败"));
            List<UploadImageResData> data = uploadRecords.stream().map(record -> {
                UploadImageResData uploadImageResData = new UploadImageResData();
                BeanUtils.copyProperties(record, uploadImageResData);
                return uploadImageResData;
            }).collect(Collectors.toList());
            return new BaseDataResDto(Status.SUCCESS).setData(data);
        } catch (Exception e) {
            e.printStackTrace();
            return new BaseDataResDto(Status.ERROR.setMessage("方法抛出异常"));
        }
    }
   
	@PostMapping("uploadAppVersionInfo")
    public BaseDataResDto uploadAppVersionInfo(@RequestBody BaseDataReqDto<AppVersionInfoReqData> param ,@RequestHeader("maijiToken") String token) {
		
	    	AppVersionInfoEntity appVersionInfoEntity = new AppVersionInfoEntity()
	    	   .setUuId(UUID_MD5.getUUID())
	    	   .setType(param.getData().getType())
	    	   .setDescription(param.getData().getDescription())
	    	   .setVersionCode(param.getData().getVersionCode())
	    	   .setUrl(param.getData().getUrl())
	    	   .setVersionName(param.getData().getVersionName())
	    	   .setInTime(new Date());
	    		appVersionInfoService.insert(appVersionInfoEntity);
	    return new BaseDataResDto(Status.SUCCESS);
    }
	
	@PostMapping("getAppVersionInfo")
    public BaseDataResDto<AppVersionInfoResData> getAppVersionInfo(@RequestBody BaseDataReqDto<Integer> param ) {
		
		if(param.getData() == null)new BaseDataResDto<AppVersionInfoResData>(Status.ERROR);
		
		EntityWrapper<AppVersionInfoEntity> wrapper = new EntityWrapper<AppVersionInfoEntity>();
		wrapper.eq("type", param.getData());
		wrapper.orderBy("in_time");
		wrapper.last("desc");

		AppVersionInfoEntity appVersionInfoEntity = appVersionInfoService.selectOne(wrapper);
		
		AppVersionInfoResData appVersionInfoResData = new AppVersionInfoResData();
		if(appVersionInfoEntity != null)BeanUtils.copyProperties(appVersionInfoEntity, appVersionInfoResData);
		
		return new BaseDataResDto<AppVersionInfoResData>(Status.SUCCESS).setData(appVersionInfoResData);
	}

    /**
     *  上传文件（批量）
     * @param reqMap
     * @param token
     * @return
     */
    @PostMapping("uploadRecord")
    public BaseDataResDto<List<UploadImageResData>> uploadRecord (@RequestBody Map<String, Map<String, Object>> reqMap,
                                                                 @RequestHeader(name = "maijiToken", required = false) String token) {
        try {
            AppUser appUser = null;
            if (StringUtil.isNotBlank(token)) appUser = appUserService.checkToken(token);
            String userId = appUser != null ? appUser.getUuId() : "ManagerUser";
            List<UploadRecord> uploadRecords = reqMap.keySet().stream().map(key -> new UploadRecord()
                        .setUuId(UUID_MD5.getUUID())
                        .setUploadUserId(userId)
                        .setBucketName((String) reqMap.get(key).get("bucketName"))
                        .setFileName(key)
                        .setWidth((Integer) reqMap.get(key).get("width"))
                        .setHeight((Integer) reqMap.get(key).get("height"))
                        .setUrl((String) reqMap.get(key).get("url"))
                        .setVideoCover((String) reqMap.get(key).get("imgUrl"))
                        .setUploadTime(new Date())
                        .setNo((Integer) reqMap.get(key).get("no"))
            ).collect(Collectors.toList());
            if (! uploadRecordService.insertBatch(uploadRecords)) return new BaseDataResDto(Status.ERROR);
            List<UploadImageResData> data = uploadRecords.stream().map(record -> {
                UploadImageResData uploadImageResData = new UploadImageResData();
                BeanUtils.copyProperties(record, uploadImageResData);
                return uploadImageResData;
            }).collect(Collectors.toList());
            return new BaseDataResDto(Status.SUCCESS).setData(data);
        } catch (Exception e) {
            e.printStackTrace();
            return new BaseDataResDto(Status.ERROR.setMessage("方法抛出异常"));
        }
    }

    /**
     * 设置资源列表的归属ID
     * @param inputDto
     * @return
     */
    @PostMapping("saveURBelongId")
    public BaseDataResDto<Boolean> saveBelongId(@RequestBody BaseInputDto<ArrayList<SaveURBelongIdReqDto>> inputDto){

        return uploadRecordService.saveBelongId(inputDto);
    }

    /**
     *  获取首页功能菜单列表
     * @param maijiToken
     * @return
     */
    @PostMapping("getFunctionMenus")
	public FunctionMenuResDto getFunctionMenus(@RequestHeader("maijiToken")String maijiToken){
		return menuService.getFunctionMenus();
	}
  
    /**
     *  获取小程序首页功能菜单列表
     * @param maijiToken
     * @return
     */
    @PostMapping("getAppletFunctionMenus")
    public FunctionMenuResDto getAppletFunctionMenus(@RequestHeader(value="maijiToken",required =false)String maijiToken){
    	return menuService.getAppletFunctionMenus();
    }

    /**
     *  发送验证码
     * @param sendCodeReqDto
     * @return
     */
    @PostMapping("sendCode")
    public TokenResDto sendCode (@RequestBody SendCodeReqDto sendCodeReqDto) {
        TokenResDto resultTokenResDto = new TokenResDto(Status.ERROR);
        Integer sendType = sendCodeReqDto.getData().getSendType();
        SMS.Template template = sendType==1? SMS.Template.UPDATEPWD: sendType==2? SMS.Template.USERLOGON: SMS.Template.LOGINCONFIRM;
        String tel = sendCodeReqDto.getData().getTel();
        JSONObject sendSms = SMS.sendSms(tel, template);
        if (sendSms.getString("Message").equals("OK")) {
            RedisUtil.setObject(maiji1RedisTemplate, "code:" + tel, UUID_MD5.md5Str(sendSms.getString("code")));
            if (maiji1RedisTemplate.expire("code:" + tel, 5, TimeUnit.MINUTES))
                resultTokenResDto.setStatus(Status.SUCCESS);
        }
        return resultTokenResDto;
    }

    /**
     *  验证token是否有效
     * @param maijiToken
     * @return
     */
    @GetMapping("checkToken/{maijiToken}")
    public BaseDataResDto<AppUser> checkToken (@PathVariable(name = "maijiToken") String maijiToken,
                                               @RequestHeader(name = "isOfficial", required = false)Boolean isOfficial) {
        if (StringUtil.isBlank(maijiToken)) return new BaseDataResDto(Status.TOKENINVALID);
        AppUser appUser = appUserService.checkToken(maijiToken, isOfficial);
        if (appUser == null) return new BaseDataResDto(Status.TOKENINVALID);
        return new BaseDataResDto(Status.SUCCESS).setData(appUser);
    }

    /**
     *  删除缓存1和缓存2的用户信息
     * @param maijiToken
     * @return
     */
    @PostMapping("deleteAppUserByRedis")
    public void deleteAppUserByRedis (@RequestBody String maijiToken) {
        if (StringUtil.isBlank(maijiToken)) appUserService.deleteAppUserByRedis(maijiToken);
    }

    /**
     *  根据标签来源获取标签列表
     * @param baseDataReqDto
     * @return
     */
    @PostMapping("findAllLabelsBySource")
    public BaseDataResDto<List<LabelResData>> findAllLabelsBySource (@RequestBody BaseDataReqDto<Label> baseDataReqDto) {
        String source = baseDataReqDto.getData().getSource();
        Integer listShow = baseDataReqDto.getData().getListShow();
        if (StringUtil.isBlank(source)) return new BaseDataResDto<>(Status.PARAMETERERROR);
        return labelService.findAllLabelsBySource(source, listShow);
    }

    /**
     *  获取标签列表
     * @param baseDataReqDto
     * @return
     */
    @PostMapping("findAllLabels")
    public BaseMetaResDto<List<LabelResData>> findAllLabels (@RequestBody BaseDataReqDto<Label> baseDataReqDto) {
        String source = baseDataReqDto.getData().getSource();
        String name = baseDataReqDto.getData().getName();
        Integer listShow = baseDataReqDto.getData().getListShow();
        if (StringUtil.isBlank(source)) return new BaseMetaResDto<>(Status.PARAMETERERROR);
        ReqMetaData metaData = baseDataReqDto.getMetaData();
        return labelService.findAllLabels(source, listShow, name, metaData);
    }

    /**
     *  添加标签
     * @param baseDataReqDto
     * @return
     */
    @PostMapping("addEditLabel")
    public BaseDataResDto<Label> addEditLabel (@RequestBody BaseDataReqDto<Label> baseDataReqDto) {
        Label label = baseDataReqDto.getData();
        if (StringUtil.isBlank(label.getName()) || StringUtil.isBlank(label.getSource())) return new BaseDataResDto<>(Status.PARAMETERERROR);
        return labelService.addEditLabel(label);
    }

    /**
     * 根据标签id获得标签集合
     * @return
     */
    @PostMapping("getLabelsByIds")
    public List<Label> getLabelsByIds (@RequestBody BaseInputDto<String> inputDto) {
		List<String> list = Arrays.asList(inputDto.getData().split(",")); 
    	return labelService.getLabelsByIds(list);
    }

    /**
     * 获取商品列表轮播图
     * @return
     */
    @PostMapping("getShoppingBannerImgs")
    public GetShoppingBannerImgsResDto getShoppingBannerImgs(){
    	return menuService.getShoppingBannerImgs();
    }

    /**
     * 获取轮播图等
     * @return
     */
    @PostMapping("findAllFunctionMemus")
    public BaseDataResDto<List<FunctionMemu>> findAllFunctionMemus (@RequestBody BaseDataReqDto<List<String>> baseDataReqDto){
        List<String> types = baseDataReqDto.getData();
        return menuService.findAllFunctionMemus (types);
    }

    /**
     * 编辑轮播图等
     * @return
     */
    @PostMapping("editFunctionMemu")
    public BaseResDto editFunctionMemu (@RequestBody BaseDataReqDto<FunctionMemu> baseDataReqDto){
        FunctionMemu data = baseDataReqDto.getData();
        return menuService.editFunctionMemu (data);
    }

    /**
     * 获取商城展示图
     * @return
     */
    @PostMapping("findShoppingImg")
    public BaseDataResDto<FunctionMemu> findShoppingImg (){
        BaseDataResDto<List<FunctionMemu>> baseDataResDto = menuService.findAllFunctionMemus(Arrays.asList("shopping_img"));
        Optional<FunctionMemu> memuOptional = baseDataResDto.getData().parallelStream().findFirst();
        if (! memuOptional.isPresent()) return new BaseDataResDto<>(Status.ERROR);
        else return new BaseDataResDto<FunctionMemu>(Status.SUCCESS).setData(memuOptional.get());
    }

    /**
     * 获取APP个人中心展示图
     * @return
     */
    @PostMapping("findAppIndexImg")
    public BaseDataResDto<FunctionMemu> findAppIndexImg (){
        BaseDataResDto<List<FunctionMemu>> baseDataResDto = menuService.findAllFunctionMemus(Arrays.asList("app_index_img"));
        Optional<FunctionMemu> memuOptional = baseDataResDto.getData().parallelStream().findFirst();
        if (! memuOptional.isPresent()) return new BaseDataResDto<>(Status.ERROR);
        else return new BaseDataResDto<FunctionMemu>(Status.SUCCESS).setData(memuOptional.get());
    }

    /**
     * 获取微信小程序个人中心展示图
     * @return
     */
    @PostMapping("findWxIndexImg")
    public BaseDataResDto<FunctionMemu> findWxIndexImg (){
        BaseDataResDto<List<FunctionMemu>> baseDataResDto = menuService.findAllFunctionMemus(Arrays.asList("wx_index_img"));
        Optional<FunctionMemu> memuOptional = baseDataResDto.getData().parallelStream().findFirst();
        if (! memuOptional.isPresent()) return new BaseDataResDto<>(Status.ERROR);
        else return new BaseDataResDto<FunctionMemu>(Status.SUCCESS).setData(memuOptional.get());
    }

    /**
     *  获取图片
     * @param id
     * @return
     */
    @PostMapping("getUploudImgs")
    public List<UploadRecord>  getUploudImgs(String id, boolean isMain){
    	return uploadRecordService.getUploudImgs(id,isMain);
    }

    /**
     *  获取App轮播图
     * @return
     */
    @PostMapping("findAppCarousel")
    public BaseDataResDto<List<UploadImageResData>>  findAppCarousel (@RequestBody BaseDataReqDto<String> baseDataReqDto){
        String name = baseDataReqDto.getData();
        if (StringUtil.isBlank(name)) return new BaseDataResDto<>(Status.PARAMETERERROR);
        return appCarouselService.findAppCarousel(name);
    }

    /**
     * 获得积分商城轮播图
     * @return
     */
    @PostMapping("getIntegralShoppingBanner")
    public BaseDataResDto<List<BannerImgsResData>>  getIntegralShoppingBanner(){
    	String type = CommonStringValueEnum.FUNCYION_MENUE_TYPE_INTEGRAL_SHOPPING_BANNNER.getValue();
    	return menuService.getBannerImgsByType(type);
    }
    
    /**
     * 获得社区动态轮播图
     * @return
     */
    @PostMapping("getCommunityBanner")
    public BaseDataResDto<List<BannerImgsResData>>  getCommunityBanner(){
    	String type = CommonStringValueEnum.FUNCYION_MENUE_TYPE_COMMUNITY_BANNNER.getValue();
    	return menuService.getBannerImgsByType(type);
    }
    
    /**
     * 校验验证码
     * @param param
     * @return
     */
    @PostMapping("checkCode")
    public BaseDataResDto<Boolean> checkCode(@RequestBody BaseDataReqDto<CheckCodeReqData> param){
    	if(StringUtils.isBlank(param.getData().getTel()) || StringUtils.isBlank(param.getData().getCode()))return new BaseDataResDto<Boolean>(Status.PARAMETERERROR);
    	Boolean bool = appUserService.checkCode(param.getData().getTel(), param.getData().getCode());
    	return new BaseDataResDto<Boolean>(Status.SUCCESS).setData(bool);
    }

}
